import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class SolitaireBattleshipCanvas extends Canvas
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static int SCALE_FACTOR = 50;
	private Random rand;
	private Board board;
	private BoardResult boardResult;
	private Map<Integer, Color> lengthToColorMap;
	private List<Integer> columnActualList;
	private List<Integer> rowActualList;
	private int width;
	private int height;
	public JFrame frame;
	
	public SolitaireBattleshipCanvas(Board board, int typeCount)
    {
		this(board, typeCount, "");
    }
	
    public SolitaireBattleshipCanvas(Board board, int typeCount, String title)
    {
    	this.board = board;
    	this.width = (board.width+1) * SCALE_FACTOR;
    	this.height = (board.height+1) * SCALE_FACTOR;
        this.frame = new JFrame();
        frame.setSize(this.width + 17, this.height + 39);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(this);
        frame.setVisible(true);
        frame.setTitle(title);
        rand = new Random();
        
        this.columnActualList = new ArrayList<Integer>();
        this.rowActualList = new ArrayList<Integer>();
        this.lengthToColorMap = new HashMap<Integer, Color>();
        
        for (int i=0; i<typeCount+1; i++)
        {
        	//Hardcode first 5 colors
        	if (i==0)
        	{
        		this.lengthToColorMap.put(i, Color.BLUE);
        	}
        	else if (i==1)
        	{
        		this.lengthToColorMap.put(i, new Color(197, 217, 241));
        	} else if (i==2) {
        		this.lengthToColorMap.put(i, new Color(146, 208, 80));
        	} else if (i==3) {
        		this.lengthToColorMap.put(i, Color.YELLOW);
        	} else if (i==4) {
        		this.lengthToColorMap.put(i, new Color(255, 192, 0));
        	} else {
				int r = rand.nextInt(256);
				int g = rand.nextInt(256);
				int b = rand.nextInt(256);
	        	this.lengthToColorMap.put(i, new Color(r, g, b));
        	}
        }        
    }
 
    public void setBoardResult(BoardResult boardResult)
    {
    	this.boardResult = boardResult;
    	
    	int columnCount = 0;
        int rowCount = 0;
        char[][] populatedBoard = boardResult.populatedBoard;
        this.columnActualList.clear();
        this.rowActualList.clear();
        
        //column count
		for (int i=0; i<populatedBoard.length; i++)
		{
            columnCount = 0;
            
			for (int j=0; j<populatedBoard[i].length; j++)
			{
                if (populatedBoard[i][j] != '0')
                    columnCount++;
			}
			
			this.columnActualList.add(columnCount);
		}
        
		for (int i=0; i<populatedBoard[0].length; i++)
		{
            rowCount = 0;
            
			for (int j=0; j<populatedBoard.length; j++)
			{
                if (populatedBoard[j][i] != '0')
                    rowCount++;
			}
			
			this.rowActualList.add(rowCount);
		}
		
    	this.repaint();
    }
    
    public void close()
    {
    	this.frame.dispose();
    }
    
    public void saveToFile(String fileName)
    {
        try
        {
            BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = image.createGraphics();
            this.paint(graphics2D);
            ImageIO.write(image,"jpeg", new File(fileName));
        }
        catch(Exception exception)
        {
            //code
        }
    }
    
    public void paint(Graphics graphics)
    {   
    	graphics.setColor(Color.WHITE);
    	graphics.fillRect(0, 0, this.width, this.height);
    	graphics.setColor(Color.BLACK);
    	graphics.drawRect(0, 0, this.width, this.height);
    	
        if (boardResult != null)
        {
        	//Column actual vs target
        	for (int i=0; i<columnActualList.size(); i++)
        	{
        		int actual = columnActualList.get(i);
        		int target = board.columnTargetList.get(i);
        		
        		String drawText = actual + " / " + target;
        		
        		if (actual == target)
        		{
        			graphics.setColor(new Color(0,100,0));
        		}
        		else
        		{
        			graphics.setColor(Color.RED);
        		}
    			
        		graphics.drawString(drawText
        				,(int) (((i+1) * SCALE_FACTOR) + (SCALE_FACTOR / 3.5)) 
        				,(int) (SCALE_FACTOR - 7));
        	}
        	
        	//Row actual vs target
        	for (int i=0; i<rowActualList.size(); i++)
        	{
        		int actual = rowActualList.get(i);
        		int target = board.rowTargetList.get(i);
        		
        		String drawText = actual + " / " + target;
        		
        		if (actual == target)
        		{
        			graphics.setColor(new Color(0,100,0));
        		}
        		else
        		{
        			graphics.setColor(Color.RED);
        		}
    			
        		graphics.drawString(drawText
          				,(int) (SCALE_FACTOR - 25)
        				,(int) (((i+1) * SCALE_FACTOR) + (SCALE_FACTOR / 1.75)));
        	}
        	
        	//Board
        	char[][] populatedBoard = boardResult.populatedBoard;
        	
    		for (int i=0; i<populatedBoard.length; i++)
    		{
    			for (int j=0; j<populatedBoard[i].length; j++)
    			{
    				int drawX = j + 1;
    				int drawY = i + 1;
    				
        			Color color = new Color(0, 0, 0);
        			String drawText = "";
        			
        			if (this.lengthToColorMap.containsKey(populatedBoard[j][i] - '0'))
        			{
        				color = this.lengthToColorMap.get(populatedBoard[j][i] - '0');
        			}
        				        		
        			graphics.setColor(color);
	        		graphics.fillRect(
	        			drawX * SCALE_FACTOR, 
	        			drawY * SCALE_FACTOR, 
	        			SCALE_FACTOR, 
	        			SCALE_FACTOR);
	        		
        			graphics.setColor(Color.BLACK);
	        		graphics.drawRect(
		        			drawX * SCALE_FACTOR, 
		        			drawY * SCALE_FACTOR, 
		        			SCALE_FACTOR, 
		        			SCALE_FACTOR);
	        		
	        		if (populatedBoard[j][i] != '0')
	        		{
	        			drawText = "" + populatedBoard[j][i];
	        		}
	        		
	        		if (! drawText.equals(""))
	        		{
	        			graphics.setColor(Color.BLACK);
		        		graphics.drawString(drawText
		        				,(int) ((drawX * SCALE_FACTOR) + (SCALE_FACTOR / 2.1)) 
		        				,(int) ((drawY * SCALE_FACTOR) + (SCALE_FACTOR / 1.75)));
	        		}
    			}
    		}
        		
        }
    }
}
